/**
 * 
 */
package fr.ece.ing4.montecarlo.client;

import java.io.Serializable;
import java.util.Random;

import fr.ece.ing4.montecarlo.compute.Task;

/**
 * @author enzo
 *
 */
public class MonteCarloSimulation implements Task<Double>,Serializable {
	private String callPutFlag;
	private double s, x, r, t, b, v;
	private int nSteps, nSimu;
	private double res, time;
	
	public MonteCarloSimulation(String c, Double s, Double x, double t, double r,double b, double v, int nSteps, int nSim)
	{
		callPutFlag=c;
		this.s=s;
		this.x=x;
		this.t=t;
		this.r=r;
		this.b=b;
		this.v=v;
		this.nSteps=nSteps;
		this.nSimu=nSim;
	}
	public double MonteCarloStandardOption() {
		double dt, st;
		double sum = 0, drift, vSqrdt;
		int i, j, z = 0;
		Random random = new Random();

		dt = this.t / this.nSteps;
		drift = (this.b - this.v * this.v / 2) * dt;
		vSqrdt = this.v * Math.sqrt(dt);
		if (this.callPutFlag.contentEquals("c"))
			z = 1;
		else if (this.callPutFlag.contentEquals("p"))
			z = -1;
		for (i = 1; i <= this.nSimu; i++) {
			st = this.s;
			for (j = 1; j <= this.nSteps; j++) {
				st = st * Math.exp(drift + vSqrdt * random.nextGaussian());
			}
			sum = sum + Math.max(z * (st - this.x), 0);
			
		}
		
		System.out.println("res:"+Math.exp(-this.r * this.t) * (sum / this.nSimu));
		return Math.exp(-this.r * this.t) * (sum / this.nSimu);
		
	}
	@Override
	public Double execute() {
		// TODO Auto-generated method stub
		return Double.valueOf(MonteCarloStandardOption());
	}

}
